package com.jfirer.validator.path.api;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import javax.validation.ElementKind;
import javax.validation.Path;
import javax.validation.Path.Node;
import com.jfirer.validator.path.PathImpl;
import com.jfirer.validator.path.node.BeanNodeImpl;
import com.jfirer.validator.path.node.ConstructorNodeImpl;
import com.jfirer.validator.path.node.CrossParameterNodeImpl;
import com.jfirer.validator.path.node.MethodNodeImpl;
import com.jfirer.validator.path.node.NodeImpl;
import com.jfirer.validator.path.node.ParameterNodeImpl;
import com.jfirer.validator.path.node.PropertyNodeImpl;
import com.jfirer.validator.path.node.ReturnValueNodeImpl;
import javax.validation.ValidationException;

public class ConnectionNodeImpl implements ConnectionNode
{
	private final ConnectionNode	pred;
	private String					name		= null;
	private boolean					inIterable	= false;
	private Integer					index		= null;
	private Object					key			= null;
	private ElementKind				elementKind	= null;
	private Integer					parameterIndex;
	private String					parameterName;
	private Method					method;
	private Constructor<?>			constructor;
	
	public ConnectionNodeImpl()
	{
		pred = null;
	}
	
	public ConnectionNodeImpl(ConnectionNode pred)
	{
		this.pred = pred;
	}
	
	@Override
	public ConnectionNode next()
	{
		return new ConnectionNodeImpl(this);
	}
	
	@Override
	public ConnectionNode setName(String name)
	{
		this.name = name;
		return this;
	}
	
	@Override
	public ConnectionNode setIndex(Integer index)
	{
		this.index = index;
		return this;
	}
	
	@Override
	public ConnectionNode setKey(Object key)
	{
		this.key = key;
		return this;
	}
	
	@Override
	public ConnectionNode setElementKind(ElementKind elementKind)
	{
		this.elementKind = elementKind;
		return this;
	}
	
	@Override
	public ConnectionNode pred()
	{
		return pred;
	}
	
	@Override
	public Node asNode()
	{
		NodeImpl nodeImpl = null;
		switch (elementKind)
		{
			case BEAN:
				nodeImpl = new BeanNodeImpl();
				nodeImpl.setName(name);
				break;
			case CONSTRUCTOR:
				nodeImpl = new ConstructorNodeImpl(constructor);
				break;
			case CROSS_PARAMETER:
				nodeImpl = new CrossParameterNodeImpl();
				break;
			case METHOD:
				nodeImpl = new MethodNodeImpl(method);
				break;
			case PARAMETER:
				nodeImpl = new ParameterNodeImpl(parameterIndex, parameterName);
				break;
			case PROPERTY:
				nodeImpl = new PropertyNodeImpl();
				nodeImpl.setName(name);
				break;
			case RETURN_VALUE:
				nodeImpl = new ReturnValueNodeImpl();
				break;
			default:
				ValidationException exception = new ValidationException("节点类型错误，无法转化");
				throw exception;
		}
		nodeImpl.setIndex(index);
		nodeImpl.setKey(key);
		nodeImpl.setElementKind(elementKind);
		nodeImpl.setInIterable(inIterable);
		return nodeImpl;
	}
	
	@Override
	public Path toPath()
	{
		return new PathImpl(this);
	}
	
	@Override
	public ConnectionNode setMethod(Method method)
	{
		this.method = method;
		return this;
	}
	
	@Override
	public ConnectionNode setConstructor(Constructor<?> constructor)
	{
		this.constructor = constructor;
		return this;
	}
	
	@Override
	public ConnectionNode setParameterIndexAndName(Integer parameterIndex, String parameterName)
	{
		this.parameterIndex = parameterIndex;
		this.parameterName = parameterName;
		return this;
	}
	
	@Override
	public ConnectionNode setInIterable(boolean inIterable)
	{
		this.inIterable = inIterable;
		return this;
	}
	
}
